#ifndef __IENUM_HELPER_H__
#define __IENUM_HELPER_H__

#include "ienum_impl.h"
#include "exceptions.h"

namespace Boss

{
  BOSS_DECLARE_RUNTIME_EXCEPTION(IEnumHelper)

  class IEnumHelper
  {
  public:
    typedef RefObjPtr<IEnum> IEnumPtr;
    typedef RefObjPtr<IBase> IBasePtr;

    IEnumHelper(IEnum *enumerator)
      : Enumerator(enumerator)
    {
      if (!Enumerator.Get())
        throw IEnumHelperException("Empty IEnum pointer");
    }
    IEnumHelper(IEnumPtr enumerator)
      : Enumerator(enumerator)
    {
      if (!Enumerator.Get())
        throw IEnumHelperException("Empty IEnum pointer");
    }
    IEnumHelper(const IEnumHelper &enumHelper)
    {
      if (enumHelper.Enumerator->Clone(Enumerator.GetPPtr()) != rcOk)
        throw IEnumHelperException("Can't clone enum");
    }
    IEnumHelper& operator = (const IEnumHelper &enumHelper)
    {
      IEnumHelper Tmp(enumHelper);
      Enumerator.Swap(Tmp.Enumerator);
      return *this;
    }
    IBasePtr First()
    {
      IBasePtr Ret;
      if (Enumerator->First() != rcOk)
        throw IEnumHelperException("Can't get first item");
      TResult Code = Enumerator->Next(Ret.GetPPtr());
      if (Code != rcOk && Code != rcFalse)
        throw IEnumHelperException("Can't get first item");
      return Ret;
    }
    IBasePtr Next()
    {
      IBasePtr Ret;
      TResult Code = Enumerator->Next(Ret.GetPPtr());
      if (Code != rcOk && Code != rcFalse)
        throw IEnumHelperException("Can't get next item");
      return Ret;
    }

  private:
    IEnumPtr Enumerator;
  };

}

#endif  // !__IENUM_HELPER_H__
